package com.onemile.utils;

/**
 * ���ܹ���
 */
public class UtiMobileCrypto
{
	/**
	 * ����
	 * 
	 * @param input
	 *            ����
	 * @param key
	 *            ��Կ
	 * @return ʮ����Ʊ��������
	 * @throws Exception
	 */
	public static String encrypt(String input, String key) throws Exception
	{
		// ���ĺ���Կ
		byte[] p = input.getBytes("utf-8");
		byte[] k = key.getBytes("utf-8");
		
		// �����ĳ�������һ������һ���ֽ� 8 λ�ֳ������ֽ��д洢
		byte[] w = new byte[p.length * 2];
		for (int i = 0; i < p.length; i++)
		{
			w[i] = (byte) ((p[i] & 0xF0) >> 4);
			w[w.length - i - 1] = (byte) (p[i] & 0x0F);
		}
		
		// �����ȴ��� 128 �����ºϲ����ָ����ĳ���
		byte[] t = null;
		if (w.length > 128)
		{
			t = new byte[w.length / 2 + 1];
			t[0] = 0;
			for (int i = 0; i < w.length - 1; i += 2)
			{
				t[i / 2 + 1] = (byte) ((w[i] << 4) + w[i + 1]);
			}
		}
		else
		{
			t = new byte[w.length + 1];
			t[0] = 1;
			for (int i = 0; i < w.length; i++)
			{
				t[i + 1] = w[i];
			}
		}
		
		// ����
		byte[] r = new byte[t.length];
		
		// ����ȡ��Ȼ������Կ��λ���
		for (int i = 0; i < t.length; i++)
		{
			int j = i % k.length;
			r[i] = (byte) ((~t[i]) ^ k[j]);
		}
		
		return toHexString(r);
	}
	
	/**
	 * ����
	 * 
	 * @param input
	 *            ʮ����Ʊ��������
	 * @param key
	 *            ��Կ
	 * @return ����
	 * @throws Exception
	 */
	public static String decrypt(String input, String key) throws Exception
	{
		// ���ĺ���Կ
		byte[] c = fromHexString(input);
		byte[] k = key.getBytes("utf-8");
		
		// ��������Կ��λ���Ȼ��ȡ��
		byte[] p = new byte[c.length];
		for (int i = 0; i < c.length; i++)
		{
			int j = i % k.length;
			p[i] = (byte) (~((c[i]) ^ k[j]));
		}
		
		// ���ĳ���û�б�����һ��
		byte[] t = null;
		if (p[0] == 0)
		{
			t = new byte[(p.length - 1) * 2];
			for (int i = 1; i < p.length; i++)
			{
				t[(i - 1) * 2] = (byte) ((p[i] & 0xF0) >> 4);
				t[i * 2 - 1] = (byte) (p[i] & 0x0F);
			}
		}
		else
		{
			t = new byte[p.length - 1];
			for (int i = 1; i < p.length; i++)
			{
				t[i - 1] = p[i];
			}
		}
		
		// ��ȡԭʼ����
		byte[] w = new byte[t.length / 2];
		for (int i = 0; i < w.length; i++)
		{
			w[i] = (byte) ((t[i] << 4) + t[t.length - i - 1]);
		}
		
		return new String(w, "utf-8");
	}
	
	/**
	 * �� byte ����ת���� 16 �����ַ�
	 * 
	 * @param bytes
	 * @return
	 */
	public static String toHexString(byte[] bytes)
	{
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < bytes.length; i++)
		{
			String hex = Integer.toHexString(bytes[i] & 0xFF);
			if (hex.length() == 1)
			{
				hex = '0' + hex;
			}
			sb.append(hex.toUpperCase());
		}
		return sb.toString();
	}
	
	/**
	 * �� 16 �����ַ�ת��Ϊ byte ����
	 * 
	 * @param s
	 * @return
	 */
	public static byte[] fromHexString(String s)
	{
		if (s.length() < 1)
		{
			return null;
		}
		
		byte[] result = new byte[s.length() / 2];
		for (int i = 0; i < s.length() / 2; i++)
		{
			int high = Integer.parseInt(s.substring(i * 2, i * 2 + 1), 16);
			int low = Integer.parseInt(s.substring(i * 2 + 1, i * 2 + 2), 16);
			result[i] = (byte) ((high << 4) + low);
		}
		return result;
	}
}
